﻿using Assets.Core.Common.Web;
using Essensoft.Paylink.WeChatPay;
using Masuit.Tools;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.PlatformAbstractions;
using Microsoft.OpenApi.Models;
using Nucleic.Core.Utils;
using Nucleic.Web.Filters;
using Nucleic.Web.Jobs;
using Nucleic.Web.Swagger;
using Quartz;
using Quartz.Impl;
using Senparc.Weixin.MP.AdvancedAPIs.TemplateMessage;
using Senparc.Weixin.MP.AdvancedAPIs;
using System.ComponentModel;
using System.Diagnostics;
using WmsToVna.Util;
using Senparc.Weixin.RegisterServices;
using Senparc.CO2NET.RegisterServices;
using Senparc.CO2NET;
using Senparc.Weixin.Entities;
using Senparc.Weixin;
using Microsoft.Extensions.Options;
using Senparc.CO2NET.AspNet;
using Senparc.CO2NET.Cache;
using Senparc.Weixin.MP.Containers;

namespace Nucleic.Web
{
    public class Startup
    {
        public Startup(IConfiguration configuration)
        {
            Configuration = configuration;
        }

        public IConfiguration Configuration { get; }
        TaskManager _manager = new TaskManager();
        public async void ConfigureServices(IServiceCollection services)
        {
            // Add services to the container.
            NlogConfig.Config();
          
            var token = Stopwatch.GetTimestamp().ToBinary(36);
            services.AddControllers(options =>
            {
                options.Filters.Add(typeof(MyExceptionFilterAttribute), 100);
            }).ConfigureApiBehaviorOptions(options =>
            {
                //使用自定义模型验证
                options.InvalidModelStateResponseFactory = (context) =>
                {
                    var errmsg = string.Join(Environment.NewLine, context.ModelState.Values.SelectMany(v => v.Errors.Select(e => e.ErrorMessage)));
                    
                    return new JsonResult(Result.fail(errmsg));
                };
            });


            // Learn more about configuring Swagger/OpenAPI at https://aka.ms/aspnetcore/swashbuckle
            services.AddEndpointsApiExplorer();
            services.AddSwaggerGen(options =>
            {
                foreach (var item in XmlCommentsFilePath)
                {
                    options.IncludeXmlComments(item);
                }

                //定义授权
                var scheme = new OpenApiSecurityScheme()
                {
                    Description = "header token",
                    Reference = new OpenApiReference
                    {
                        Type = ReferenceType.SecurityScheme,
                        Id = "token"
                    },
                    Scheme = "",
                    Name = "token",// 默认参数名称
                    In = ParameterLocation.Header,//默认存放Authorization信息的位置（请求头）
                    Type = SecuritySchemeType.ApiKey,
                };
                options.AddSecurityDefinition("token", scheme);

                //全部加授权
                //var requirement = new OpenApiSecurityRequirement();
                //requirement[scheme] = new List<string>();
                //options.AddSecurityRequirement(requirement);
                //只有某个注解的才开启授权锁
                options.OperationFilter<AuthResponsesOperationFilter>();
            });
            services.AddWeChatPay();
            services.AddLogging(log =>
            {
                log.AddLog4Net("log4net.config");
            });
            services.Configure<WeChatPayOptions>(Configuration.GetSection("WeChatPay"));

            services.AddSingleton<ISchedulerFactory, StdSchedulerFactory>();
            services.AddSingleton<OrderJob>();
            //services.AddSingleton<QuartzFactory>();

            //BackgroundWorker bk = new BackgroundWorker();
            //bk.DoWork += delegate
            //{
            //    _manager.Run();
            //};
            //bk.RunWorkerCompleted += delegate
            //{

            //};
            //bk.RunWorkerAsync();
            

            ////Senparc.Weixin 注册（必须）
            services.AddMemoryCache();//使用本地缓存必须添加
            services.AddSenparcWeixinServices(Configuration);
           
        }
        public void Configure(IApplicationBuilder app, IWebHostEnvironment env, IOptions<SenparcSetting> senparcSetting, IOptions<SenparcWeixinSetting> senparcWeixinSetting)
        {
            //if (env.IsDevelopment())
            {
                app.UseSwagger();
                app.UseSwaggerUI();
            }
            app.UseCors(builder =>
            {
                builder.AllowAnyOrigin()
                       .AllowAnyHeader()
                       .AllowAnyMethod()
                       .SetPreflightMaxAge(TimeSpan.FromSeconds(2000000));
            });


            app.UseStaticFiles();

            app.UseRouting();
            var registerService = app.UseSenparcGlobal(env, senparcSetting.Value, globalRegister =>
            {
                
               
            },true).UseSenparcWeixin(senparcWeixinSetting.Value, (weixinRegister, weixinSetting) => {
                
                AccessTokenContainer.RegisterAsync(senparcWeixinSetting.Value.WeixinAppId, senparcWeixinSetting.Value.WeixinAppSecret);
            });
            app.UseAuthorization();
            app.UseEndpoints(endpoints =>
            {

                endpoints.MapControllerRoute("default", "{controller=Home}/{action=Index}/{id?}");
                endpoints.MapControllerRoute("defaultWithArea", "{area}/{controller=Home}/{action=Index}/{id?}");
            });
            if (true)
            {
                //var qu=app.
            }
            

        }
        static List<string> XmlCommentsFilePath
        {
            get
            {
                var basePath = PlatformServices.Default.Application.ApplicationBasePath;
                DirectoryInfo d = new DirectoryInfo(basePath);
                FileInfo[] files = d.GetFiles("*.xml");
                var xmls = files.Select(a => Path.Combine(basePath, a.FullName)).ToList();
                return xmls;
            }
        }  
        /// <summary>
           /// 初步判断当前配置是否满足使用 Memcached（根据是否已经修改了默认配置字符串判断）
           /// </summary>
           /// <param name="senparcSetting"></param>
           /// <returns></returns>
        private bool UseMemcached(SenparcSetting senparcSetting, out string memcachedConfigurationStr)
        {
            memcachedConfigurationStr = senparcSetting.Cache_Memcached_Configuration;
            var useMemcached = !string.IsNullOrEmpty(memcachedConfigurationStr) && memcachedConfigurationStr != "#{Cache_Memcached_Configuration}#";
            return useMemcached;
        }
    }    
}
